﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;

public static class Geo
{

    public class GeoArea
    {
        public int pointNum;
        public List<Vector2> pointSet;
        public GeoArea(List<Vector2> v)
        {
            this.pointSet = v;
        }
        public GeoArea(int num, List<Vector2> v)
        {
            this.pointNum = num;
            this.pointSet = v;
        }
        public virtual bool isPointInArea(float x, float y)
        {
            return false;
        }
    }
    public class PolyArea : GeoArea
    {
        public PolyArea(int num, List<Vector2> v) : base(num, v)
        {
            if (v.Count != num)
            {
                Debug.LogError("GEO: POLY POINT NUM DOES NOT MATCH");
            }
        }
        public override bool isPointInArea(float pointX, float pointY)
        {
            int crossNum = 0;
            for (int i = 0; i < this.pointNum; i++)
            {
                Vector2 v1 = this.pointSet[i];
                Vector2 v2 = this.pointSet[(i + 1) % pointNum];
                if (((v1.y <= pointY) && (v2.y > pointY))
                    || ((v1.y > pointY) && (v2.y <= pointY)))
                {
                    if (pointX < v1.x + (pointX - v1.y) / (v2.y - v1.y) * (v2.x - v1.x))
                    {
                        crossNum++;
                    }
                }
            }
            return crossNum % 2 != 0;
        }
    }

    /// <summary>
    /// 0---------------1
    /// |               |
    /// 3---------------2
    /// </summary>
    public class Quad : GeoArea
    {
        public Quad(List<Vector2> v) : base(v)
        {
            this.pointNum = 4;
            if (v.Count != 4)
            {
                Debug.LogError("GEO: QUAD POINT NUM DOES NOT MATCH");
            }
        }
        public override bool isPointInArea(float pointX, float pointY)
        {
            if (pointX > pointSet[0].x && pointX < pointSet[1].x && pointY > pointSet[3].y && pointY < pointSet[0].y)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    public class Circle : GeoArea
    {
        public float r;
        public Circle(List<Vector2> v, float rr) : base(v)
        {
            this.pointNum = 1;
            this.r = rr;
            if (v.Count != 1)
            {
                Debug.LogError("GEO: CIRCLE POINT NUM DOES NOT MATCH");
            }
        }
        public override bool isPointInArea(float pointX, float pointY)
        {
            if ((pointX - pointSet[0].x) * (pointX - pointSet[0].x) + (pointY - pointSet[0].y) * (pointY - pointSet[0].y) < r * r)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    public static Vector3 ChunkCoordIntToWorld(Vector3Int coord)
    {
        int x = coord.x;
        int y = coord.y;
        float xx = x * TerrianManager.VOXELSIZE;
        xx = xx >= 0 ? xx - TerrianManager.HALFVOXELSIZE : xx + TerrianManager.HALFVOXELSIZE;
        float yy = y * TerrianManager.VOXELSIZE;
        yy = yy >= 0 ? yy - TerrianManager.HALFVOXELSIZE : yy + TerrianManager.HALFVOXELSIZE;
        return new Vector3(xx, yy, 0);
    }
    //public static Vector3Int WorldToChunkCoordInt(Vector3 coord)
    //{
    //    //!!!Chunk边界上的谁也不属于
    //    tmpX = coord.x > 0 ? tmpX + 1 : tmpX - 1;
    //    tmpY = coord.y > 0 ? tmpY + 1 : tmpY - 1;
    //    return new Vector3Int(tmpX, tmpY, 0);

    //}
}
